/**  
* Copyright (c) 2009, Noel Lynch All rights reserved. Redistribution and use  
* in source and binary forms, with or without modification, are permitted  
* provided that the following conditions are met: Redistributions of source  
* code must retain the above copyright notice, this list of conditions and the  
* following disclaimer. Redistributions in binary form must reproduce the above  
* copyright notice, this list of conditions and the following disclaimer in the  
* documentation and/or other materials provided with the distribution. Neither  
* the name of Noel Lynch nor the names of contributors may be used to  
* endorse or promote products derived from this software without specific prior  
* written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
*/
// created by noellynch
// Sep 28, 2009

package com.sceneworker.editors.texturepainter.brushgenerator;

import java.awt.Color;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

public class BrushImagePaint implements Paint {

	protected	IQuadraticBrushSpectrum		mcl_spectrum;
	
	private		BrushImageGeneratorContext		mcl_context;
	public	BrushImagePaint(IQuadraticBrushSpectrum cl_s) {
		mcl_spectrum = cl_s;
	}
	
	public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
			Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
		if(mcl_context == null) {
			mcl_context = new BrushImageGeneratorContext(mcl_spectrum);
		}
		
		return mcl_context;
	}

	public int getTransparency() {
		return OPAQUE;
	}
	
	public class BrushImageGeneratorContext implements PaintContext {

		private		IQuadraticBrushSpectrum		mcl_spectrum;
		private		int					mia_data[];
		
		public	BrushImageGeneratorContext(IQuadraticBrushSpectrum cl_spec) {
			mcl_spectrum = cl_spec;
		}
		
		public void dispose() {
		}

		public ColorModel getColorModel() {
			return ColorModel.getRGBdefault();
		}

		public Raster getRaster(int x, int y, int w, int h) {
			WritableRaster		lcl_raster = getColorModel().createCompatibleWritableRaster(w, h);
			
			if(mia_data == null) {
				mia_data = new int[w * h * 4];
			}
			
			
			Point2D		lcl_c = new Point2D.Double(mcl_spectrum.getSamples(), mcl_spectrum.getSamples());
			Point2D		lcl_d = new Point2D.Double(0, 0);
			double		lf_distance;
			double		lf_new;
			int			li_newColor;
			int			li_base;
			
			for(int li_j = 0; li_j < h; li_j++) {
				for(int li_i = 0; li_i < w; li_i++) {
					li_base = ((li_j * w) + li_i) * 4;
					lcl_d.setLocation(li_i, li_j);
					lf_distance = lcl_c.distance(lcl_d);
					
					if(lf_distance > mcl_spectrum.getSamples()) {
						lf_distance = mcl_spectrum.getSamples();
					}
					
					lf_new = mcl_spectrum.sampleAtX(lf_distance / mcl_spectrum.getSamples());
					li_newColor = (int)(255 * lf_new);
					
					if(li_newColor > 255) {
						li_newColor = 255;
					} else if(li_newColor < 0) {
						li_newColor = 0;
					}
					
					//System.out.println(String.format("%.2f (%.2f): %d, %d", lf_new, lf_distance, li_i, li_j));
					mia_data[li_base] = li_newColor;
					mia_data[li_base + 1] = li_newColor;
					mia_data[li_base + 2] = li_newColor;
					mia_data[li_base + 3] = 255;
				}
			}
			
			lcl_raster.setPixels(0, 0, w, h, mia_data);
			
			return lcl_raster;
		}
	}
}